<?php

/**
 * 佣金计算类
 * 
 * @file CommissionCalculate.php
 * @author yff
 * @date 2018-8-14
 */

namespace App\Http\ManagerApi\Classes;

use App\Http\ManagerApi\Models\PlatformSetting;
use App\Http\ManagerApi\Models\User as PlatformUser;
use App\Http\ManagerApi\Models\TeamMember;
use Illuminate\Support\Facades\DB;
use App\Http\ManagerApi\Models\UserIntegralLog;
use App\Http\ManagerApi\Models\PlatformRangeSetting;

class CommissionCalculate
{
    // 当前注册用户
    private $current_register_uid;

    // 当前推荐人对象
    private $current_user;

    // 当前下级
    private $current_sub_uid;

    // 当前所获佣金
    private $current_commission = 0;

    // 当前级差
    private $current_range = 0;

    // 当前报单金额
    private $price;

    // 平台设置对象
    private $setting;

    // 平台级差设置对象
    private $range;

    /**
     * 构造方法
     * @param int $super_uid 推荐人uid
     */
    public function __construct(int $super_uid, int $sub_uid, int $price)
    {
        if (!isset($super_uid, $sub_uid, $price)) {
            die('缺少参数！');
        }

        $this->current_register_uid = $sub_uid;

        $this->current_user = PlatformUser::findOrFail($sub_uid);

        //$this->current_sub_uid = $sub_uid;

        $this->setting = $setting = PlatformSetting::firstOrFail();

        $this->range = PlatformRangeSetting::firstOrFail();

        $this->price = $price;

        // 直属上级佣金
        $this->current_commission = floor(($price - $price * $setting->service_charge_rate) * $setting->direct_rate * 10) / 10;
    }

    /**
     * 递归计算上级获取佣金
     * 如果达到返利条件，每次都会返利
     */
    public function calculateCommission1()
    {
        DB::beginTransaction();

        // 获取下级人数
        $sub_number = $this->getSubNumber();

        // 获取上级对象
        $super = $this->getSuper();
        
        // 返利
        $rebate = 0;

        // 判断是否已达获取返利条件
        if ($sub_number >= $this->setting->sub_max_number && isset($super)) {

            // 上级返利
            $rebate = (int)((int)($this->current_commission * $this->setting->commission_rate) * $this->setting->sub_rebate_rate);
        }
        
        // 更新当前用户积分、总积分
        $this->current_user->total_integral += ($this->current_commission + $rebate);
        $this->current_user->integral += ($this->current_commission + $rebate);
        $res = $this->current_user->save();

        // 插入积分记录表
        $create = [
            'uid' => $this->current_user->id,
            'changed_integral' => $this->current_commission + $rebate,
            'current_integral' => $this->current_user->integral,
            'type' => 1,
            'flag' => 1,
            'is_finished' => 1,
            'desc' => '分红'
        ];
        $log = UserIntegralLog::create($create);

        if (!$res && !$log) {
            DB::rollback();
        }

        if (isset($super)) {

            $this->current_commission = (int)($this->current_commission * $this->setting->commission_rate);

            $this->current_user = $super;

            // 递归
            $this->calculateCommission();
        }

        DB::commit();
    }

    /**
     * 递归计算上级获取佣金
     * 如果达到返利条件，只会返利一次
     */
    public function calculateCommission2()
    {
        DB::beginTransaction();

        // 获取下级人数
        $sub_number = $this->getSubNumber();

        // 获取上级对象
        $super = $this->getSuper();
        
        // 更新当前用户积分、总积分
        $this->current_user->total_integral += $this->current_commission;
        $this->current_user->integral += $this->current_commission;
        $res = $this->current_user->save();

        // 插入积分记录表
        $create = [
            'uid' => $this->current_user->id,
            'from_sub_uid' => $this->current_sub_uid,
            'changed_integral' => $this->current_commission,
            'current_integral' => $this->current_user->integral,
            'type' => 1,
            'is_finished' => 1,
            'desc' => '佣金'
        ];
        $log = UserIntegralLog::create($create);

        if (!$res && !$log) {
            DB::rollback();
        }

        // 返利
        $rebate = 0;

        // 判断当前注册用户是否当前用户直属下级
        $is_sub = $this->isSub();

        // 判断是否已达获取返利条件
        if ($sub_number == $this->setting->sub_max_number && isset($super) && $is_sub) {

            // 获取上级得到当前推荐人的总工资
            $total_commission = UserIntegralLog::where('uid', $super->id)->where('from_sub_uid', $this->current_user->id)->sum('changed_integral');

            // 计算返利
            $rebate = (int)(($total_commission + (int)($this->current_commission * $this->setting->commission_rate)) * $this->setting->sub_rebate_rate);

            // 更新当前用户积分、总积分
            $this->current_user->total_integral += $rebate;
            $this->current_user->integral += $rebate;
            $res = $this->current_user->save();

            // 插入积分记录表
            $create = [
                'uid' => $this->current_user->id,
                'from_sub_uid' => $this->current_sub_uid,
                'changed_integral' => $rebate,
                'current_integral' => $this->current_user->integral,
                'type' => 1,
                'is_finished' => 1,
                'desc' => '返利'
            ];
            $log = UserIntegralLog::create($create);

            if (!$res && !$log) {
                DB::rollback();
            }
        }

        if (isset($super)) {

            $this->current_commission = (int)($this->current_commission * $this->setting->commission_rate);

            $this->current_sub_uid = $this->current_user->id;

            $this->current_user = $super;

            // 递归
            $this->calculateCommission();
        }

        DB::commit();
    }

    /**
     * 递归计算上级获取佣金
     * 如果达到返利条件，只会返利一次(总工资),超过每次都会返利
     */
    public function calculateCommission3()
    {
        DB::beginTransaction();

        // 获取下级人数
        $sub_number = $this->getSubNumber();

        // 获取上级对象
        $super = $this->getSuper();
        
        // 更新当前用户积分、总积分
        $this->current_user->total_integral += $this->current_commission;
        $this->current_user->integral += $this->current_commission;
        $res = $this->current_user->save();

        // 插入积分记录表
        $create = [
            'uid' => $this->current_user->id,
            'from_sub_uid' => $this->current_sub_uid,
            'changed_integral' => $this->current_commission,
            'current_integral' => $this->current_user->integral,
            'flag' => 1,
            'type' => 1,
            'is_finished' => 1,
            'desc' => '分红'
        ];
        $log = UserIntegralLog::create($create);

        if (!$res && !$log) {
            DB::rollback();
        }

        // 返利
        $rebate = 0;

        // 判断当前注册用户是否当前用户直属下级
        $is_sub = $this->isSub();

        // 判断是否已达获取返利条件（总工资返利）
        if ($sub_number == $this->setting->sub_max_number && isset($super) && $is_sub) {

            // 获取上级得到当前推荐人的总工资
            $total_commission = UserIntegralLog::where('uid', $super->id)->where('from_sub_uid', $this->current_user->id)->sum('changed_integral');

            // 计算返利
            $rebate = (int)(($total_commission + (int)($this->current_commission * $this->setting->commission_rate)) * $this->setting->sub_rebate_rate);

            // 更新当前用户积分、总积分
            $this->current_user->total_integral += $rebate;
            $this->current_user->integral += $rebate;
            $res = $this->current_user->save();

            // 插入积分记录表
            $create = [
                'uid' => $this->current_user->id,
                'from_sub_uid' => $this->current_sub_uid,
                'changed_integral' => $rebate,
                'current_integral' => $this->current_user->integral,
                'flag' => 1,
                'type' => 1,
                'is_finished' => 1,
                'desc' => '总返利'
            ];
            $log = UserIntegralLog::create($create);

            if (!$res && !$log) {
                DB::rollback();
            }
        }

        $rebate = 0;
        // 判断是否达返利条件（次次返）
        if ($sub_number >= $this->setting->sub_max_number && isset($super)) {

            if ($sub_number == $this->setting->sub_max_number && $is_sub) {
                $rebate = 0;
            } else {
                $rebate = (int)((int)($this->current_commission * $this->setting->commission_rate) * $this->setting->sub_rebate_rate);
            }

            if ($rebate) {

            // 更新当前用户积分、总积分
                $this->current_user->total_integral += $rebate;
                $this->current_user->integral += $rebate;
                $res = $this->current_user->save();

            // 插入积分记录表
                $create = [
                    'uid' => $this->current_user->id,
                    'from_sub_uid' => $this->current_sub_uid,
                    'changed_integral' => $rebate,
                    'current_integral' => $this->current_user->integral,
                    'flag' => 1,
                    'type' => 1,
                    'is_finished' => 1,
                    'desc' => '返利'
                ];
                $log = UserIntegralLog::create($create);

                if (!$res && !$log) {
                    DB::rollback();
                }
            }
        }

        if (isset($super)) {

            $this->current_commission = (int)($this->current_commission * $this->setting->commission_rate);

            $this->current_sub_uid = $this->current_user->id;

            $this->current_user = $super;

            // 递归
            $this->calculateCommission();
        }

        DB::commit();
    }

    /**
     * 递归计算当前用户收益
     * 1分享收益 2管理收益 3店面分红 4店面收益 5运营中心分红 6股东分红
     */
    public function calculateCommission()
    {
        DB::transaction(function () {

            // 获取直属上级对象
            $super = $this->getSuper();

            if (isset($super) && $this->current_commission >= 1) {

                // 当前用户是注册用户
                if ($this->current_user->id == $this->current_register_uid) {

                    // 上级分享收益
                    // 更新直属上级积分、总积分
                    $super->total_integral += $this->current_commission;
                    $super->integral += floor($this->current_commission * 9) / 10;
                    $super->point += floor($this->current_commission) / 10;
                    $res = $super->save();

                    // 插入积分记录表
                    $create = [
                        'uid' => $super->id,
                        'from_sub_uid' => $this->current_user->id,
                        'changed_integral' => $this->current_commission,
                        'current_integral' => $super->integral,
                        'type' => 1,
                        'flag' => 1,
                        'is_finished' => 1,
                        'desc' => '分享收益'
                    ];
                    UserIntegralLog::create($create);

                } else {
                    
                    // 上级管理收益
                    // 更新直属上级积分、总积分
                    $super->total_integral += $this->current_commission;
                    $super->integral += floor($this->current_commission * 9) / 10;
                    $super->point += floor($this->current_commission) / 10;
                    $res = $super->save();

                    // 插入积分记录表
                    $create = [
                        'uid' => $super->id,
                        'from_sub_uid' => $this->current_user->id,
                        'changed_integral' => $this->current_commission,
                        'current_integral' => $super->integral,
                        'type' => 2,
                        'flag' => 1,
                        'is_finished' => 1,
                        'desc' => '管理收益'
                    ];
                    UserIntegralLog::create($create);
                }

                // 店面分红
                // 获取直属上级满足返利的下级id(当前用户除外)
                $sub_uids = $this->getRebateUsers($super->id);
                $rebate = 0;
                $rebate = floor($this->current_commission * $this->setting->sub_rebate_rate / (count($sub_uids) + 1) * 10) / 10;
                // 更新当前用户积分、总积分
                if ($rebate > 0) {

                    $this->current_user->total_integral += $rebate;
                    $this->current_user->integral += floor($rebate * 9) / 10;
                    $this->current_user->point += floor($rebate) / 10;
                    $res = $this->current_user->save();

                    // 插入积分记录表
                    $create = [
                        'uid' => $this->current_user->id,
                        'changed_integral' => $rebate,
                        'current_integral' => $this->current_user->integral,
                        'type' => 3,
                        'flag' => 1,
                        'is_finished' => 1,
                        'desc' => '店面分红'
                    ];
                    UserIntegralLog::create($create);

                    // 更新加权返利用户积分、总积分
                    if (count($sub_uids)) {

                        foreach ($sub_uids as $suid) {
                            $user = PlatformUser::find($suid);
                            if (!isset($usere)) {
                                continue;
                            }
                            $user->total_integral += $rebate;
                            $user->integral += floor($rebate * 9) / 10;
                            $user->point += floor($rebate) / 10;
                            $res = $user->save();

                            // 插入积分记录表
                            $create = [
                                'uid' => $suid,
                                'changed_integral' => $rebate,
                                'current_integral' => $user->integral,
                                'type' => 3,
                                'flag' => 1,
                                'is_finished' => 1,
                                'desc' => '店面分红'
                            ];
                            UserIntegralLog::create($create);
                        }
                    }
                }
            }
            
            // 级差
            $range = $this->getRange();
            $range_diff = ($range * 100 - $this->current_range * 100) / 100 > 0 ? ($range * 100 - $this->current_range * 100) / 100 : 0;
            // 更新当前级差
            $this->current_range = max($this->current_range, $range);
            $range_award = floor(($this->price - $this->price * $this->setting->service_charge_rate) * $range_diff * 10) / 10;
            // 更新当前用户积分、总积分
            if ($range_award > 0) {

                $this->current_user->total_integral += $range_award;
                $this->current_user->integral += floor($range_award * 9) / 10;
                $this->current_user->point += floor($range_award) / 10;
                $this->current_user->save();

                // 插入积分记录表
                $create = [
                    'uid' => $this->current_user->id,
                    'changed_integral' => $range_award,
                    'current_integral' => $this->current_user->integral,
                    'type' => 4,
                    'flag' => 1,
                    'is_finished' => 1,
                    'desc' => '店面收益'
                ];
                UserIntegralLog::create($create);
            }

            // 运营中心分红
            $partners = PlatformUser::where('is_active', 1)
                ->where('is_partner', 1)
                ->get();
            if (count($partners)) {
                $partner_award = floor(($this->price - $this->price * $this->setting->service_charge_rate) * $this->setting->partner_rate * 10) / 10;
                foreach ($partners as $user) {
                    $user->total_integral += $partner_award;
                    $user->integral += floor($partner_award * 9) / 10;
                    $user->point += floor($partner_award) / 10;
                    $res = $user->save();

                    // 插入积分记录表
                    $create = [
                        'uid' => $user->id,
                        'changed_integral' => $partner_award,
                        'current_integral' => $user->integral,
                        'type' => 5,
                        'flag' => 1,
                        'is_finished' => 1,
                        'desc' => '运营中心分红'
                    ];
                    UserIntegralLog::create($create);
                }
            }

            // 股东分红
            $shareholders = PlatformUser::where('is_active', 1)
                ->where('is_shareholder', 1)
                ->get();
            if (count($shareholders)) {
                $partner_award = floor(($this->price - $this->price * $this->setting->service_charge_rate) * $this->setting->shareholder_rate / count($shareholders) * 10) / 10;
                foreach ($shareholders as $user) {
                    $user->total_integral += $partner_award;
                    $user->integral += floor($partner_award * 9) / 10;
                    $user->point += floor($partner_award) / 10;
                    $res = $user->save();

                    // 插入积分记录表
                    $create = [
                        'uid' => $user->id,
                        'changed_integral' => $partner_award,
                        'current_integral' => $user->integral,
                        'type' => 6,
                        'flag' => 1,
                        'is_finished' => 1,
                        'desc' => '股东分红'
                    ];
                    UserIntegralLog::create($create);
                }
            }

            // 更新业绩
            if ($this->current_user->id != $this->current_register_uid) {

                $this->current_user->total_achievement += floor(($this->price - $this->price * $this->setting->service_charge_rate) * 10) / 10;
                $this->current_user->save();
            }

            if (isset($super) && $this->current_commission >= 1) {

                $this->current_commission = floor($this->current_commission * $this->setting->commission_rate * 10) / 10;

                $this->current_user = $super;

                // 递归
                $this->calculateCommission();
            }
        });
    }

    /**
     * 获取当前用户下级人数
     */
    public function getSubNumber()
    {
        return TeamMember::where('uid', $this->current_user->id)->count();
    }

    /**
     * 获取当前用户上级
     */
    public function getSuper()
    {
        $sup_uid = TeamMember::where('sub_uid', $this->current_user->id)->value('uid');

        return PlatformUser::find($sup_uid);
    }

    /**
     * 判断当前注册用户是否是当前用户的直属下级
     */
    public function isSub()
    {
        return TeamMember::where('uid', $this->current_user->id)->where('sub_uid', $this->current_register_uid)->exists();
    }

    /**
     * 获取当前用户直属上级满足返利条件人id
     */
    public function getRebateUsers($sup_uid)
    {
        $sub_uids = TeamMember::where('uid', $sup_uid)->where('sub_uid', '<>', $this->current_user->id)->pluck('sub_uid');
        $return = [];
        foreach ($sub_uids as $sub_uid) {
            $sub_count = TeamMember::where('uid', $sub_uid)->count();
            // 是否满足返利条件
            $sub_count >= $this->setting->sub_max_number ? $return[] = $sub_uid : null;
        }

        return $return;
    }

    /**
     * 获取当前用户级差比
     */
    public function getRange()
    {
        if ($this->current_user->total_achievement <= 0) {
            $range = 0;
        } else {
            $rate = PlatformRangeSetting::where('condition', '<=', $this->current_user->total_achievement / 10000)->max('rate');
            $range = isset($rate) ? $rate : 0;
        }

        return $range;
    }
}